Число называется
свободным от квадратов, если оно не делится ни на один полный квадрат, кроме 1.
Вам необходимо подсчитать их!
Вход. Первая строка содержит количество тестов t. Каждая из следующих t строк содержит одно натуральное число n (n
≤ 1014).
Выход. Вывести t строк, каждая из которых содержит
количество натуральных свободных от квадратов чисел, не больших n.
Пример
входа |
Пример
выхода |
3 1 1000 100000000000000 |
1 608 60792710185947 |
функция Мебиуса
Анализ алгоритма
Подсчитаем количество натуральных чисел,
не больших n, свободных от квадратов,
используя формулу включения-исключения. Пусть 2 = p1 < p2
< … < pk – множество
всех простых чисел, не больших . Тогда по формуле включений-исключений искомое количество
чисел равно
Q(n) = n
– + – + …
Пусть n = 30. Имеется три простых числа, не больших : p1 =
2, p2 = 3 и p3 = 5. По формуле
Q(30) = 30 – – – + + + – = 30 – 7 – 3 – 1 = 19
Если первое слагаемое n рассматривать как n / 12, то можно утверждать, что сумма Q(n) состоит из слагаемых вида , где 1 ≤ i
≤ (для i > соответствующие суммы
равны нулю). Причем слагаемое имеет знак плюс, если i является произведением четного
количества разных простых чисел, и знак минус, если i является произведением нечетного количества разных простых чисел.
Однако отметим, что в первом случае µ(i) = 1, а во втором µ(i) = -1. Поэтому
значение Q(n) можно переписать через
функцию Мебиуса:
Q(n) =
Учитывая, что
если i свободно от квадратов, то = 1. Следовательно
=
Пример
При n = 30 имеем:
Q(30) = µ(1) + µ(2) + µ(3) + µ(4) + µ(5) =
= 30 – 7 – 3 + 0
– 1 = 19
Реализация
алгоритма
Объявим
константы и глобальные массивы.
#define MAX 10000010
#define LMAX 700000
int lp[MAX+1] = {0}, primes[LMAX], mu[MAX] = {0};
Линейный Эратосфен. lp[i]
содержит наименьший простой делитель числа i.
void LinearEratosfen(void)
{
int i, j;
for (i = 2; i <= MAX; ++i)
{
if (lp[i] == 0)
{
lp[i] = i;
primes[cnt++] =
i;
}
for (j = 0; j < cnt && primes[j] <=
lp[i] && i * primes[j] <= MAX; j++)
lp[i * primes[j]]
= primes[j];
}
}
Вычисление функции Мебиуса используя массив lp.
void calc_Mobius(void)
{
int i, q;
mu[1] = 1;
for(i = 2; i < MAX; i++)
{
q = i / lp[i];
if (q % lp[i] != 0) mu[i] = -mu[q];
}
}
Основная часть программы. Вычисляем функцию Мебиуса для всех
значений от 1 до MAX.
LinearEratosfen();
calc_Mobius();
Читаем входные данные.
scanf("%d",&tests);
while(tests--)
{
scanf("%lld",&n);
Количество чисел, свободных от квадрратов, вычисляем по
формуле:
Q(n) =
sum = 0; sqn =
sqrt(1.0*n);
for(i = 1; i <= sqn; i++)
sum += (n / (i *
i)) * mu[i];
Выводим ответ.
printf("%lld\n",sum);
}